package com.open.pdf;

import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.List;
import com.lowagie.text.ListItem;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

@SpringBootTest
public class CreateTablePDF {

    @Test
    public void createTablePDF(){
        Font font8 = FontFactory.getFont(FontFactory.HELVETICA, 8);

        // step 1
        Document document = new Document(PageSize.A4);

        try {
            // step 2
            PdfWriter writer = PdfWriter.getInstance(document,
                    new FileOutputStream("d:/testPDF/tables.pdf"));
            float width = document.getPageSize().getWidth();
            float height = document.getPageSize().getHeight();
            // step 3
            document.open();

            // step 4
            float[] columnDefinitionSize = { 33.33F, 33.33F, 33.33F };

            float pos = height / 2;
            PdfPTable table = null;
            PdfPCell cell = null;

            table = new PdfPTable(columnDefinitionSize);
            table.getDefaultCell().setBorder(0);
            table.setHorizontalAlignment(0);
            table.setTotalWidth(width - 72);
            table.setLockedWidth(true);

            cell = new PdfPCell(new Phrase("Table added with document.add()"));
            cell.setColspan(columnDefinitionSize.length);
            table.addCell(cell);
            table.addCell(new Phrase("Louis Pasteur", font8));
            table.addCell(new Phrase("Albert Einstein", font8));
            table.addCell(new Phrase("Isaac Newton", font8));
            table.addCell(new Phrase("8, Rabic \n street", font8));
            table.addCell(new Phrase("2 Photons Avenue", font8));
            table.addCell(new Phrase("32 Gravitation Court", font8));
            table.addCell(new Phrase("39100 Dole France", font8));
            table.addCell(new Phrase("12345 Ulm Germany", font8));
            table.addCell(new Phrase("45789 Cambridge  England", font8));

            document.add(table);

            table = new PdfPTable(columnDefinitionSize);
            table.getDefaultCell().setBorder(0);
            table.setHorizontalAlignment(0);
            table.setTotalWidth(width - 72);
            table.setLockedWidth(true);

            cell = new PdfPCell(new Phrase("Table added with writeSelectedRows"));
            cell.setColspan(columnDefinitionSize.length);
            table.addCell(cell);
            table.addCell(new Phrase("Louis Pasteur", font8));
            table.addCell(new Phrase("Albert Einstein", font8));
            table.addCell(new Phrase("Isaac Newton", font8));
            table.addCell(new Phrase("8, Rabic street", font8));
            table.addCell(new Phrase("2 Photons Avenue", font8));
            table.addCell(new Phrase("32 Gravitation Court", font8));
            table.addCell(new Phrase("39100 Dole France", font8));
            table.addCell(new Phrase("12345 Ulm Germany", font8));
            table.addCell(new Phrase("45789 Cambridge  England \n Cambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \nCambridge  England \n", font8));

            table.writeSelectedRows(0, -1, 50, pos, writer.getDirectContent());
        }

        catch (DocumentException | IOException de) {
            System.err.println(de.getMessage());
        }
        // step 5
        document.close();
    }

    @Test
    public void createAddBigTablePDF(){

        System.out.println("document.add(BigTable)");
        // step1
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        try {
            // step2
            PdfWriter.getInstance(document,
                    new FileOutputStream("d:/testPDF/AddBigTable.pdf"));
            // step3
            document.open();
            // step4
            String[] bogusData = { "M0065920", "SL", "FR86000P", "PCGOLD",
                    "119000", "96 06", "2001-08-13", "4350", "6011648299",
                    "FLFLMTGP", "153", "119000.00" };
            int NumColumns = 12;

            PdfPTable datatable = new PdfPTable(NumColumns);
            int[] headerwidths = {9, 4, 8, 10, 8, 11, 9, 7, 9, 10, 4, 10}; // percentage
            datatable.setWidths(headerwidths);
            datatable.setWidthPercentage(100); // percentage
            datatable.getDefaultCell().setPadding(3);
            datatable.getDefaultCell().setBorderWidth(2);
            datatable.getDefaultCell().setHorizontalAlignment(
                    Element.ALIGN_CENTER);
            datatable.addCell("Clock #");
            datatable.addCell("Trans Type");
            datatable.addCell("Cusip");
            datatable.addCell("Long Name");
            datatable.addCell("Quantity");
            datatable.addCell("Fraction Price");
            datatable.addCell("Settle Date");
            datatable.addCell("Portfolio");
            datatable.addCell("ADP Number");
            datatable.addCell("Account ID");
            datatable.addCell("Reg Rep ID");
            datatable.addCell("Amt To Go ");

            datatable.setHeaderRows(1); // this is the end of the table header

            datatable.getDefaultCell().setBorderWidth(1);
            for (int i = 1; i < 750; i++) {
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(0.9f);
                }
                for (int x = 0; x < NumColumns; x++) {
                    datatable.addCell(bogusData[x]);
                }
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(1);
                }
            }
            document.add(datatable);
        } catch (Exception de) {
            de.printStackTrace();
        }
        // step5
        document.close();
    }


    @Test
    public void createAlignmentPDF(){

        System.out.println("indentation - alignment");
        // step1
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        try {
            // step2
            PdfWriter.getInstance(document,
                    new FileOutputStream("d:/testPDF/Alignment.pdf"));
            // step3
            document.open();
            // step4
            PdfPTable table = new PdfPTable(2);
            PdfPCell cell;
            Paragraph p = new Paragraph("Quick brown fox jumps over the lazy dog. Quick brown fox jumps over the lazy dog.");
            table.addCell("default alignment");
            cell = new PdfPCell(p);
            table.addCell(cell);
            table.addCell("centered alignment");
            cell = new PdfPCell(p);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell);
            table.addCell("right alignment");
            cell = new PdfPCell(p);
            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            table.addCell(cell);
            table.addCell("justified alignment");
            cell = new PdfPCell(p);
            cell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED);
            table.addCell(cell);
            table.addCell("blah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\n");
            table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BASELINE);
            table.addCell("baseline");
            table.addCell("blah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\n");
            table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
            table.addCell("bottom");
            table.addCell("blah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\n");
            table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
            table.addCell("middle");
            table.addCell("blah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\nblah\n");
            table.getDefaultCell().setVerticalAlignment(Element.ALIGN_TOP);
            table.addCell("top");
            document.add(table);
        } catch (Exception de) {
            de.printStackTrace();
        }
        // step5
        document.close();
    }

    @Test
    public void createSplitRowPDF(){

        System.out.println("Split rows");
        // step1
        Document document1 = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        Document document2 = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        Document document3 = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        try {
            // step2
            PdfWriter.getInstance(document1,
                    new FileOutputStream("d:/testPDF/SplitRowsBetween.pdf"));
            PdfWriter.getInstance(document2,
                    new FileOutputStream("d:/testPDF/SplitRowsWithin.pdf"));
            PdfWriter.getInstance(document3,
                    new FileOutputStream("d:/testPDF/OmitRows.pdf"));
            // step3
            document1.open();
            document2.open();
            document3.open();
            // step4
            String text = "Quick brown fox jumps over the lazy dog. ";
            for (int i = 0; i < 5; i++) text += text;
            PdfPTable table = new PdfPTable(2);
            PdfPCell largeCell;
            Phrase phrase;
            for (int i = 0; i < 10; i++) {
                phrase = new Phrase(text);
                for (int j = 0; j < i; j++) {
                    phrase.add(new Phrase(text));
                }
                if (i == 7) phrase = new Phrase(text);
                table.addCell(String.valueOf(i));
                largeCell = new PdfPCell(phrase);
                table.addCell(largeCell);
            }
            document1.add(table);
            table.setSplitLate(false);
            document2.add(table);
            table.setSplitRows(false);
            document3.add(table);
        } catch (Exception de) {
            de.printStackTrace();
        }
        // step5
        document1.close();
        document2.close();
        document3.close();
    }

    @Test
    public void createTableSpacingPDF(){
        System.out.println("TableSpacing");
        // step1
        Document document = new Document(PageSize.A4);
        try {
            // step2
            PdfWriter.getInstance(document,
                    new FileOutputStream("d:/testPDF/TableSpacing.pdf"));
            // step3
            document.open();
            // step4
            PdfPTable table = new PdfPTable(3);
            PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 3"));
            cell.setColspan(3);
            table.addCell(cell);
            table.addCell("1.1");
            table.addCell("2.1");
            table.addCell("3.1");
            table.addCell("1.2");
            table.addCell("2.2");
            for (int i = 0; i < 200; i++) {
                table.addCell("We add 2 tables,\n but with a certain");
            }
            cell = new PdfPCell(new Paragraph("cell test1"));
            cell.setBorderColor(new Color(255, 0, 0));
            table.addCell(cell);
            cell = new PdfPCell(new Paragraph("cell test2"));
            cell.setColspan(2);
            cell.setBackgroundColor(new Color(0xC0, 0xC0, 0xC0));
            table.addCell(cell);
            table.setWidthPercentage(50);
            document.add(new Paragraph("We add 2 tables:"));
            document.add(table);
            document.add(table);
            document.add(new Paragraph("They are glued to eachother"));
            document.add(table);
            document.newPage();
            document.add(new Paragraph("We add 2 tables, but with a certain 'SpacingBefore':"));
            table.setSpacingBefore(15f);
            document.add(table);
            document.add(table);
            document.add(new Paragraph("Unfortunately, there was no spacing after."));
            table.setSpacingAfter(15f);
            document.add(table);
            document.add(new Paragraph("This is much better, don't you think so?"));
        } catch (Exception de) {
            de.printStackTrace();
        }
        // step5
        document.close();
    }

    @Test
    public void createTableRowSpacingPDF(){
        System.out.println("Old Table class");
        // step 1: creation of a document-object
        Document document = new Document();
        try {
            // step 2: creation of the writer-object
            PdfWriter.getInstance(document, new FileOutputStream("rowTable.pdf"));
            // step 3: we open the document
            document.open();
            // step 4: we create a table and add it to the document
            Table table = new Table(3);
            table.setBorderWidth(1);
            table.setBorderColor(new Color(0, 0, 255));
            table.setPadding(5);
            table.setSpacing(5);
            Cell cell = new Cell("header");
            cell.setHeader(true);
            cell.setColspan(3);
            table.addCell(cell);
            cell = new Cell("example cell with colspan 1 and rowspan 2");
            cell.setRowspan(2);
            cell.setBorderColor(new Color(255, 0, 0));
            table.addCell(cell);
            table.addCell("1.1");
            table.addCell("2.1");
            table.addCell("1.2");
            table.addCell("2.2");
            table.addCell("cell test1");
            cell = new Cell("big cell");
            cell.setRowspan(2);
            cell.setColspan(2);
            cell.setBackgroundColor(new Color(0xC0, 0xC0, 0xC0));
            table.addCell(cell);
            table.addCell("cell test2");
            document.add(table);
        }
        catch(DocumentException | IOException de) {
            System.err.println(de.getMessage());
        }
        // step 5: we close the document
        document.close();
    }

    @Test
    public void createLongListPDF() throws FileNotFoundException {
        System.out.println("the Long List example");
        // step 1: creation of a document-object
        Document document = new Document();
        // step 2:
        PdfWriter.getInstance(document, new FileOutputStream("d:/testPDF/longList.pdf"));
        // step 3: we open the document
        document.open();
        // step 4:
        List list = new List(true);
        for (int i = 0; i < 30; i++) {
            list.add(new ListItem("This is the line with the number " + (i + 1)
                    + ". Don't worry if the line is very long, but we need to a line break."));
        }
        document.add(list);
        // step 5: we close the document
        document.close();
    }
}
